/*

Copyright 2007 Renaun Erickson (http://renaun.com)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ignore
*/
package asfslib
{
	
import asfslib.api.familytree.v1.User;
import asfslib.events.FamilySearchErrorEvent;
import asfslib.events.FamilySearchServiceEvent;

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLStream;
import flash.net.URLVariables;


[Event(name="loginSuccess", type="asfslib.events.FamilySearchServiceEvent")]
	
[Event(name="error", type="asfslib.events.FamilySearchErrorEvent")]	

/**
 * Provides a single object to login into the FamilySearch web service.
 *
 * @author Renaun Erickson
 */	
public class FamilySearchService extends EventDispatcher
{

    //--------------------------------------------------------------------------
    //
    //  Constants
    //
    //--------------------------------------------------------------------------

    public static const PROPERTIES_SERVICE:String = 			"properties";

    /**
     *  identity endpoint and services
     */
    public static const IDENTITY_SERVICES:String = 				"identity";
    public static const IDENTITY_VERSION_STRING:String = 		"v1";
    
    public static const LOGIN_SERVICE:String = 					"login";   
    public static const LOGOUT_SERVICE:String = 				"logout";
	
    /**
     *  familytree endpoint and services
     */
    public static const FAMILY_TREE_SERVICES:String = 			"familytree";
    public static const FAMILY_TREE_VERSION_STRING:String = 	"v1";
    
    public static const PERSON_SERVICE:String = 				"person";
    public static const SEARCH_SERVICE:String = 				"search";
    public static const USER_SERVICE:String = 					"user";
    public static const MATCH_SERVICE:String = 					"match";
	
    /**
     *  authorities endpoint and services
     */
    public static const AUTHORITIES_SERVICES:String = 			"authorities";
    public static const AUTHORITIES_VERSION_STRING:String = 	"v1";
    
    public static const PLACE_SERVICE:String = 					"place";
    public static const NAME_SERVICE:String = 					"name";
    public static const DATE_SERVICE:String = 					"date";
    public static const CULTURE_SERVICE:String = 				"culture";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------


    /**
     *  Constructor.
     */
    public function FamilySearchService()
    {
    	super();
    
        if (!identityURLoader)
        {
        	identityURLoader = new URLStream();
				
        	identityURLoader.addEventListener(Event.COMPLETE, identityCompleteLoader);
        	identityURLoader.addEventListener("httpResponseStatus", httpStatusHandler);
        	identityURLoader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
	
	/**
	 *  URLLoader responsible for making family tree calls
	 */
	private var identityURLoader:URLStream;
	
	/**
	 *  URLLoader responsible for making family tree calls
	 */
	private var familytreeURLoader:URLLoader;
	
	private var user:User;
	
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
	
	/**
	 * 	Current services URL  (will change in the future)
	 */
	public var familySearchURL:String = "http://www.dev.usys.org/";
	
	[Bindable("connectedChange")]
	public var connected:Boolean = false;
	
	/**
	 * 	Store the id for this FamilySearch service session
	 */
	public var sessionID:String = "";

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
	
    /**
     *  Makes a login attempt with the following username and password values.
     *
     * 	@param username  username to login as.
     * 	@param password  Corresponding password.
     */
    public function login(username:String, password:String):void 
    {
		var urlRequest:URLRequest = new URLRequest(familySearchURL + IDENTITY_SERVICES + "/" + IDENTITY_VERSION_STRING + "/" + LOGIN_SERVICE);
		urlRequest.method = URLRequestMethod.POST;

        var variables:URLVariables = new URLVariables();
        variables.username = username;
        variables.password = password;
        urlRequest.data = variables;

		identityURLoader.load(urlRequest);
    }
    
    /**
     * 	Logout
     */
    public function logout():void
    {
		var urlRequest:URLRequest = new URLRequest(familySearchURL + IDENTITY_SERVICES + "/" + IDENTITY_VERSION_STRING + "/" + LOGOUT_SERVICE);
		urlRequest.method = URLRequestMethod.POST;

        var variables:URLVariables = new URLVariables();
        variables.sessionId = sessionID;
        urlRequest.data = variables;

		identityURLoader.load(urlRequest);   
		sessionID = ""; 	
    }
    
    /**
     *	Handle the login response.
     */
    private function identityCompleteLoader(event:Event):void
    {
    	var loader:URLStream = event.target as URLStream;
    	
    	var resultXML:XML = XML(loader.readUTFBytes(loader.bytesAvailable));

		if (resultXML.namespace("") != undefined) 
		{
		    default xml namespace = resultXML.namespace("");
		}
		
		var fsapiNS:Namespace = resultXML.namespace("fsapi-" + AUTHORITIES_VERSION_STRING);
		var hasErrors:Boolean = ((resultXML.fsapiNS::errors as XMLList).length() > 0);
		if (!hasErrors)
		{
			sessionID = resultXML.session.@id;
			dispatchEvent(new FamilySearchServiceEvent(FamilySearchServiceEvent.LOGIN_SUCCESS));
  		}
  		else
  		{
  			var code:int = int(resultXML.fsapiNS::errors.fsapiNS::error.@code);
  			var message:String = resultXML.fsapiNS::errors.fsapiNS::error.fsapiNS::message;
  			dispatchEvent(new FamilySearchErrorEvent(FamilySearchErrorEvent.ERROR, false, false, message, code));
  		}
  
   		default xml namespace = new Namespace("");
    }

    /**
     *	Handle the login response.
     */
    private function httpStatusHandler(event:HTTPStatusEvent):void
    {
    	//var loader:URLStream = event.target as URLStream;
    	//var resultXML:XML = XML(loader.bytesAvailable);
    	
    	//var message:String = (event["responseHeaders"][0] as URLRequestHeader).name + " _ " + (event["responseHeaders"][0] as URLRequestHeader).value+"";
    	
    	//dispatchEvent(new FamilySearchErrorEvent(FamilySearchErrorEvent.ERROR, false, false, event.event.status);
    }

    /**
     *	Handle the login response.
     */
    private function errorHandler(event:IOErrorEvent):void
    {
    	// TODO handle error messages
    }

}

}